package thoven.achievement.net.jsonutil.service

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator
import com.google.gson.JsonParser
import java.util.Properties
import java.io.StringWriter

/**
 * 格式转换服务
 * JSON ⇌ YAML ⇌ Properties
 */
object FormatConverter {
    
    private val jsonMapper = ObjectMapper()
    private val yamlMapper = ObjectMapper(
        YAMLFactory()
            .disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER)
            .enable(YAMLGenerator.Feature.MINIMIZE_QUOTES)
    )
    
    /**
     * JSON 转 YAML
     */
    fun jsonToYaml(json: String): Result<String> {
        return try {
            // 验证 JSON 格式
            JsonParser.parseString(json)
            
            // 转换为 YAML
            val jsonNode = jsonMapper.readTree(json)
            val yaml = yamlMapper.writeValueAsString(jsonNode)
            
            Result.success(yaml)
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * YAML 转 JSON
     */
    fun yamlToJson(yaml: String): Result<String> {
        return try {
            val yamlNode = yamlMapper.readTree(yaml)
            val json = jsonMapper.writerWithDefaultPrettyPrinter().writeValueAsString(yamlNode)
            
            Result.success(json)
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * JSON 转 Properties
     * 将嵌套的 JSON 扁平化为 properties 格式
     */
    fun jsonToProperties(json: String): Result<String> {
        return try {
            val jsonElement = JsonParser.parseString(json)
            
            if (!jsonElement.isJsonObject) {
                return Result.failure(IllegalArgumentException("JSON must be an object"))
            }
            
            val properties = Properties()
            flattenJson(jsonElement.asJsonObject, "", properties)
            
            val writer = StringWriter()
            properties.store(writer, "Generated from JSON")
            
            Result.success(writer.toString())
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * Properties 转 JSON
     */
    fun propertiesToJson(propertiesText: String): Result<String> {
        return try {
            val properties = Properties()
            properties.load(propertiesText.reader())
            
            val rootMap = mutableMapOf<String, Any>()
            
            properties.forEach { key, value ->
                val keyStr = key.toString()
                val valueStr = value.toString()
                
                setNestedValue(rootMap, keyStr, valueStr)
            }
            
            val json = jsonMapper.writerWithDefaultPrettyPrinter().writeValueAsString(rootMap)
            Result.success(json)
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * 扁平化 JSON 对象
     */
    private fun flattenJson(
        jsonObject: com.google.gson.JsonObject,
        prefix: String,
        properties: Properties
    ) {
        jsonObject.entrySet().forEach { (key, value) ->
            val newKey = if (prefix.isEmpty()) key else "$prefix.$key"
            
            when {
                value.isJsonPrimitive -> {
                    properties.setProperty(newKey, value.asString)
                }
                value.isJsonObject -> {
                    flattenJson(value.asJsonObject, newKey, properties)
                }
                value.isJsonArray -> {
                    value.asJsonArray.forEachIndexed { index, item ->
                        if (item.isJsonPrimitive) {
                            properties.setProperty("$newKey[$index]", item.asString)
                        } else if (item.isJsonObject) {
                            flattenJson(item.asJsonObject, "$newKey[$index]", properties)
                        }
                    }
                }
                value.isJsonNull -> {
                    properties.setProperty(newKey, "null")
                }
            }
        }
    }
    
    /**
     * 设置嵌套值
     */
    @Suppress("UNCHECKED_CAST")
    private fun setNestedValue(map: MutableMap<String, Any>, key: String, value: String) {
        val parts = key.split(".")
        var current: MutableMap<String, Any> = map
        
        for (i in 0 until parts.size - 1) {
            val part = parts[i]
            
            // 检查是否是数组索引
            if (part.contains("[") && part.contains("]")) {
                val arrayKey = part.substringBefore("[")
                val index = part.substringAfter("[").substringBefore("]").toIntOrNull() ?: 0
                
                if (!current.containsKey(arrayKey)) {
                    current[arrayKey] = mutableListOf<Any>()
                }
                
                val list = current[arrayKey] as MutableList<Any>
                
                // 确保列表足够大
                while (list.size <= index) {
                    list.add(mutableMapOf<String, Any>())
                }
                
                if (list[index] !is MutableMap<*, *>) {
                    list[index] = mutableMapOf<String, Any>()
                }
                
                current = list[index] as MutableMap<String, Any>
            } else {
                if (!current.containsKey(part)) {
                    current[part] = mutableMapOf<String, Any>()
                }
                current = current[part] as MutableMap<String, Any>
            }
        }
        
        val lastPart = parts.last()
        
        // 处理最后一部分（可能是数组）
        if (lastPart.contains("[") && lastPart.contains("]")) {
            val arrayKey = lastPart.substringBefore("[")
            val index = lastPart.substringAfter("[").substringBefore("]").toIntOrNull() ?: 0
            
            if (!current.containsKey(arrayKey)) {
                current[arrayKey] = mutableListOf<Any>()
            }
            
            val list = current[arrayKey] as MutableList<Any>
            
            while (list.size <= index) {
                list.add("")
            }
            
            list[index] = parseValue(value)
        } else {
            current[lastPart] = parseValue(value)
        }
    }
    
    /**
     * 解析值类型
     */
    private fun parseValue(value: String): Any {
        return when {
            value == "null" -> "null"
            value == "true" -> true
            value == "false" -> false
            value.toIntOrNull() != null -> value.toInt()
            value.toDoubleOrNull() != null -> value.toDouble()
            else -> value
        }
    }
}

